Skip to content

Add /health/ready application readiness check - #781

Merged
KrzysztofPajak merged 6 commits into
developfrom
feature/readiness-health-check
Aug 13, 2026
Merged

Add /health/ready application readiness check#781
KrzysztofPajak merged 6 commits into
developfrom
feature/readiness-health-check

Conversation

@KrzysztofPajak

@KrzysztofPajak KrzysztofPajak commented Aug 13, 2026

Copy link
Copy Markdown
Member

Type: feature

Issue

The application only exposes /health/live, a health check that always returns Healthy regardless of application state. There is no /health/ready, so an orchestrator (e.g. Kubernetes) cannot distinguish "process is alive" from "instance has finished starting and is configured to serve traffic" — it may route traffic to an instance that is still starting up or was deployed before the install wizard ran.

Per explicit scope decision, this PR does not add MongoDB or Redis connectivity checks to readiness — only the application process itself is checked. Checking those dependencies is a separate, larger change (tracked as a future extension in the local architecture audit, not part of this PR).

Solution

  • Added StartupHealthCheck (Grand.Web.Common.Infrastructure.HealthChecks), an IHealthCheck that is Healthy only once:
    1. IHostApplicationLifetime.ApplicationStarted has fired (all IStartupApplication.Configure calls and hosted services have completed startup), and
    2. DataSettingsManager.DatabaseIsInstalled() reports a configured connection string (in-memory/local state, no network I/O — no MongoDB/Redis probing anywhere in this change).
  • Tagged the existing always-healthy "self" check as "live" (unchanged behavior) and registered StartupHealthCheck as "startup" tagged "ready".
  • Mapped /health/live and /health/ready with HealthCheckOptions.Predicate filtering on those tags, so /health/live keeps its exact existing behavior and /health/ready reports true application readiness.
  • Added unit tests covering all three states (not started; started but not configured; started and configured).

Design spec and implementation plan are included under docs/superpowers/ for reference.

Breaking changes

None. /health/live behavior and response are unchanged. /health/ready is a new endpoint; nothing previously depended on it.

Testing

  1. Run dotnet test src/Tests/Grand.Web.Common.Tests/Grand.Web.Common.Tests.csproj — 18/18 pass, including the 3 new StartupHealthCheckTests.
  2. Run the app (dotnet run --project src/Web/Grand.Web/Grand.Web.csproj).
  3. curl -i http://localhost:5000/health/live200 OK, body Healthy, regardless of install/DB state.
  4. curl -i http://localhost:5000/health/ready200 OK, body Healthy once the app has started and a database connection is configured; 503 Service Unavailable before that (e.g. on an instance that hasn't run the install wizard yet).

Update: dropped the docs/superpowers/ design-spec/plan files from this branch — they were working artifacts of the agentic workflow with no prior convention in this repo, not requested output. The one durable piece of rationale they carried (the DataSettingsManager.DatabaseIsInstalled() one-way caching gotcha) now lives as a comment on StartupHealthCheck.

KrzysztofPajak and others added 5 commits August 13, 2026 18:55
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Reword shipped source comments to be self-contained instead of
  pointing at an untracked local roadmap doc
  (StartupHealthCheck.cs, ServiceCollectionExtensions.cs,
  ApplicationBuilderExtensions.cs)
- Add ArgumentNullException.ThrowIfNull guard in StartupHealthCheck
  constructor
- Add a comment warning that every registered health check must carry
  a live or ready tag
- StartupHealthCheckTests: reset DataSettingsManager._instance in
  Cleanup(), replace null-forgiving operator with an explicit null
  check, add [DoNotParallelize] to the test class
- Plan: clarify which verification method covers the 503 case
- Spec: document DataSettingsManager.DatabaseIsInstalled() caching
  caveat and the need for a restart after install
Copilot AI lite review requested due to automatic review settings August 13, 2026 17:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

The design spec and implementation plan under docs/superpowers/ were
working artifacts of the agentic workflow, not established documentation
for this repo (no prior convention here) and not requested output. The
one piece of durable rationale they carried - that DataSettingsManager
.DatabaseIsInstalled() caches after its first call and can only be
forced to false, never back to true, without a process restart - now
lives as a comment on StartupHealthCheck instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@KrzysztofPajak
KrzysztofPajak merged commit 581cfc7 into develop Aug 13, 2026
4 of 5 checks passed
@KrzysztofPajak
KrzysztofPajak deleted the feature/readiness-health-check branch August 13, 2026 17:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants